import re
import difflib
# from split_legal import parse_law_file
import os
import argparse
from collections import defaultdict

def calculate_similarity(text1, text2):
    """计算两个文本的相似度"""
    return difflib.SequenceMatcher(None, text1, text2).ratio()

def extract_articles_by_line(content):
    """通过行首匹配提取法条，避免法条内容中的法条引用问题"""
    lines = content.split("\n")
    articles = []
    current_article = ""
    current_num = ""
    
    for line in lines:
        # 检查是否是新法条的开始（行首为"第X条"，考虑前面可能有全角或半角空格）
        article_match = re.match(r'^[\s　]*第([一二三四五六七八九十百千]+)条\s*(.*)$', line)
        
        # 检查是否是章节标题（如"第X章"或"第X节"，考虑前面可能有全角或半角空格）
        section_match = re.match(r'^[\s　]*第[一二三四五六七八九十]+[章节]', line)
        
        if article_match:
            # 如果已经有收集到的法条，保存它
            if current_article:
                articles.append((current_num, current_article))
            
            # 开始新的法条
            current_num = article_match.group(1)
            current_article = f"第{current_num}条 {article_match.group(2)}"
        elif section_match:
            # 遇到章节标题，结束当前法条
            if current_article:
                articles.append((current_num, current_article))
                current_article = ""
                current_num = ""
            # 章节标题不作为法条处理，直接跳过
        elif current_article:
            # 继续当前法条
            current_article += "\n" + line
    
    # 添加最后一个法条
    if current_article:
        articles.append((current_num, current_article))
    
    return articles

def find_best_match(new_article, old_articles, matched_indices, threshold=0.5):
    """为新法条寻找最匹配的旧法条"""
    best_match = None
    best_similarity = 0
    best_index = -1
    
    # 提取新法条内容（不包括法条号）
    new_num, new_content = new_article
    
    for i, old_article in enumerate(old_articles):
        if i in matched_indices:
            continue  # 跳过已经匹配过的旧法条
        
        # 提取旧法条内容（不包括法条号）
        old_num, old_content = old_article
        old_text = re.sub(r'^第[一二三四五六七八九十百千]+条\s*', '', old_content)
        new_text = re.sub(r'^第[一二三四五六七八九十百千]+条\s*', '', new_content)
        
        similarity = calculate_similarity(old_text, new_text)
        
        if similarity > best_similarity:
            best_similarity = similarity
            best_match = old_article
            best_index = i
    
    if best_similarity >= threshold:
        matched_indices.add(best_index)
        return best_match, best_similarity, best_index
    else:
        return None, 0, -1

def compare_texts_char_by_char(old_text, new_text):
    """按字符比较两个文本，返回HTML格式的差异展示"""
    matcher = difflib.SequenceMatcher(None, old_text, new_text)
    result = []
    
    for opcode, i1, i2, j1, j2 in matcher.get_opcodes():
        if opcode == 'equal':
            # 相同部分
            result.append(f'<span class="unchanged">{old_text[i1:i2]}</span>')
        elif opcode == 'delete':
            # 删除部分
            result.append(f'<span class="deleted">{old_text[i1:i2]}</span>')
        elif opcode == 'insert':
            # 插入部分
            result.append(f'<span class="added">{new_text[j1:j2]}</span>')
        elif opcode == 'replace':
            # 替换部分
            result.append(f'<span class="deleted">{old_text[i1:i2]}</span>')
            result.append(f'<span class="added">{new_text[j1:j2]}</span>')
    
    return ''.join(result)

def compare_law_files(old_file, new_file, output_dir="diff_results", threshold=0.5):
    """比较两个法律文件，生成单页HTML对比结果"""
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    
    # 读取文件内容
    with open(old_file, 'r', encoding='utf-8') as f:
        old_content = f.read()
    
    with open(new_file, 'r', encoding='utf-8') as f:
        new_content = f.read()
    
    # 直接提取法条
    old_articles = extract_articles_by_line(old_content)
    new_articles = extract_articles_by_line(new_content)
    
    # 匹配结果
    matched_indices_old = set()
    matched_new_to_old = {}  # 新法条索引 -> 旧法条索引的映射
    
    # 为每个新法条寻找最匹配的旧法条
    for i, new_article in enumerate(new_articles):
        old_article, similarity, old_index = find_best_match(new_article, old_articles, matched_indices_old, threshold)
        if old_article:
            matched_new_to_old[i] = (old_index, similarity)
    
    # 找出被删除的法条（未匹配的旧法条）
    deleted_articles = [(old_articles[i][0], old_articles[i][1]) for i in range(len(old_articles)) if i not in matched_indices_old]
    
    # 统计信息
    stats = {
        "old_file": old_file,
        "new_file": new_file,
        "old_count": len(old_articles),
        "new_count": len(new_articles),
        "matched_count": len(matched_new_to_old),
        "deleted_count": len(deleted_articles),
        "added_count": len(new_articles) - len(matched_new_to_old)
    }
    
    # 生成摘要文件
    generate_summary_file(stats, new_articles, old_articles, matched_new_to_old, deleted_articles, output_dir)
    
    # 生成HTML对比结果
    html_content = f"""<!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>法律文本对比</title>
        <style>
            :root {{
                --primary-color: #2c3e50;
                --secondary-color: #3498db;
                --accent-color: #e74c3c;
                --light-color: #ecf0f1;
                --success-color: #2ecc71;
                --warning-color: #f39c12;
                --deleted-color: #ffebe9;
                --added-color: #e6ffed;
                --border-radius: 8px;
                --shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            }}
            
            * {{
                box-sizing: border-box;
                margin: 0;
                padding: 0;
            }}
            
            body {{
                font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
                font-size: 18px;
                line-height: 1.6;
                color: var(--primary-color);
                background-color: #f9f9f9;
                padding: 0;
                margin: 0;
            }}
            
            .container {{
                max-width: 1200px;
                margin: 0 auto;
                padding: 20px;
            }}
            
            header {{
                background-color: var(--primary-color);
                color: white;
                padding: 2rem;
                text-align: center;
                margin-bottom: 2rem;
                box-shadow: var(--shadow);
            }}
            
            h1 {{
                font-size: 2.5rem;
                margin-bottom: 1rem;
            }}
            
            h2 {{
                font-size: 2rem;
                margin: 2rem 0 1rem;
                padding-bottom: 0.5rem;
                border-bottom: 2px solid var(--secondary-color);
            }}
            
            .summary {{
                background-color: white;
                padding: 1.5rem;
                border-radius: var(--border-radius);
                box-shadow: var(--shadow);
                margin-bottom: 2rem;
                font-size: 1.1rem;
            }}
            
            .summary p {{
                margin: 0.5rem 0;
            }}
            
            .article-container {{
                background-color: white;
                border-radius: var(--border-radius);
                margin-bottom: 1.5rem;
                overflow: hidden;
                box-shadow: var(--shadow);
                border-left: 5px solid #ccc;
                transition: transform 0.2s ease;
            }}
            
            .article-container:hover {{
                transform: translateY(-3px);
            }}
            
            .modified-article {{
                border-left-color: var(--warning-color);
            }}
            
            .new-article {{
                border-left-color: var(--success-color);
            }}
            
            .deleted-article {{
                border-left-color: var(--accent-color);
            }}
            
            .article-header {{
                padding: 1rem 1.5rem;
                background-color: var(--light-color);
                border-bottom: 1px solid #ddd;
                display: flex;
                justify-content: space-between;
                align-items: center;
                font-size: 1.2rem;
            }}
            
            .article-content {{
                padding: 1.5rem;
            }}
            
            pre {{
                white-space: pre-wrap;
                word-wrap: break-word;
                font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
                font-size: 18px;
                line-height: 1.6;
            }}
            
            .similarity {{
                padding: 0.3rem 0.6rem;
                border-radius: 20px;
                font-size: 0.9rem;
                color: white;
            }}
            
            .similarity-high {{
                background-color: var(--success-color);
            }}
            
            .similarity-medium {{
                background-color: var(--warning-color);
            }}
            
            .similarity-low {{
                background-color: var(--accent-color);
            }}
            
            .unchanged {{
                color: inherit;
            }}
            
            .deleted {{
                background-color: var(--deleted-color);
                text-decoration: line-through;
                color: var(--accent-color);
                padding: 0 2px;
                border-radius: 3px;
            }}
            
            .added {{
                background-color: var(--added-color);
                color: var(--success-color);
                padding: 0 2px;
                border-radius: 3px;
            }}
            
            .deleted-section, .modified-section {{
                margin-top: 2rem;
            }}
            
            @media (max-width: 768px) {{
                body {{
                    font-size: 16px;
                }}
                
                .container {{
                    padding: 10px;
                }}
                
                h1 {{
                    font-size: 2rem;
                }}
                
                h2 {{
                    font-size: 1.5rem;
                }}
            }}
        </style>
    </head>
    <body>
        <header>
            <h1>法律文本对比</h1>
            <p>新旧法条变化自动对比分析</p>
        </header>
        
        <div class="container">
            <div class="summary">
                <p><strong>旧版文件:</strong> {old_file}</p>
                <p><strong>新版文件:</strong> {new_file}</p>
                <p><strong>旧版法条总数:</strong> {stats["old_count"]}</p>
                <p><strong>新版法条总数:</strong> {stats["new_count"]}</p>
                <p><strong>匹配的法条数:</strong> {stats["matched_count"]}</p>
                <p><strong>删除的法条数:</strong> {stats["deleted_count"]}</p>
                <p><strong>新增的法条数:</strong> {stats["added_count"]}</p>
            </div>
            
            <h2>法条对比 (按新版法条顺序)</h2>
    """
    
    # 按新版法条顺序展示所有法条对比
    for i, (new_num, new_content) in enumerate(new_articles):
        if i in matched_new_to_old:
            # 这是修改过的法条
            old_index, similarity = matched_new_to_old[i]
            old_num, old_content = old_articles[old_index]
            
            similarity_class = "similarity-high" if similarity > 0.8 else "similarity-medium" if similarity > 0.6 else "similarity-low"
            
            # 去掉法条号后比较内容
            old_text = re.sub(r'^第[一二三四五六七八九十百千]+条\s*', '', old_content)
            new_text = re.sub(r'^第[一二三四五六七八九十百千]+条\s*', '', new_content)
            
            # 生成差异比较HTML
            diff_content = compare_texts_char_by_char(old_text, new_text)
            
            html_content += f"""
            <div class="article-container modified-article">
                <div class="article-header">
                    <strong>第{new_num}条</strong> <span>(原: 第{old_num}条)</span>
                    <span class="similarity {similarity_class}">相似度: {similarity:.2f}</span>
                </div>
                <div class="article-content">
                    <pre>{diff_content}</pre>
                </div>
            </div>
            """
        else:
            # 这是新增的法条
            new_text = re.sub(r'^第[一二三四五六七八九十百千]+条\s*', '', new_content)
            html_content += f"""
            <div class="article-container new-article">
                <div class="article-header">
                    <strong>第{new_num}条</strong> <span>(新增)</span>
                </div>
                <div class="article-content">
                    <pre class="added">{new_text}</pre>
                </div>
            </div>
            """
    
    # 放到末尾：展示被删除的法条
    if deleted_articles:
        html_content += """
            <h2>完全删除的法条</h2>
            <div class="deleted-section">
        """
        
        # 展示被删除的法条
        for num, article_content in deleted_articles:
            article_text = re.sub(r'^第[一二三四五六七八九十百千]+条\s*', '', article_content)
            html_content += f"""
                <div class="article-container deleted-article">
                    <div class="article-header">
                        <strong>第{num}条</strong> <span>(已删除)</span>
                    </div>
                    <div class="article-content">
                        <pre class="deleted">{article_text}</pre>
                    </div>
                </div>
            """
        html_content += "</div>"
    
    html_content += """
        </div>
    </body>
    </html>
    """
    
    with open(os.path.join(output_dir, "law_comparison.html"), "w", encoding="utf-8") as f:
        f.write(html_content)
    
    return stats

def generate_summary_file(stats, new_articles, old_articles, matched_new_to_old, deleted_articles, output_dir):
    """生成摘要文本文件"""
    summary = f"""法律文本对比摘要
            ================

            旧版文件: {stats["old_file"]}
            新版文件: {stats["new_file"]}

            旧版法条总数: {stats["old_count"]}
            新版法条总数: {stats["new_count"]}
            匹配的法条数: {stats["matched_count"]}
            删除的法条数: {stats["deleted_count"]}
            新增的法条数: {stats["added_count"]}

            删除的法条:
            """
    
    for article_num, _ in deleted_articles:
        summary += f"- 第{article_num}条\n"
    
    summary += "\n新增的法条:\n"
    
    for i, (article_num, _) in enumerate(new_articles):
        if i not in matched_new_to_old:
            summary += f"- 第{article_num}条\n"
    
    summary += "\n修改的法条对应关系:\n"
    
    for new_index, (old_index, similarity) in matched_new_to_old.items():
        old_num = old_articles[old_index][0]
        new_num = new_articles[new_index][0]
        summary += f"- 旧版第{old_num}条 --> 新版第{new_num}条 (相似度: {similarity:.2f})\n"
    
    with open(os.path.join(output_dir, "summary.txt"), "w", encoding="utf-8") as f:
        f.write(summary)

# 主函数
def main():
    parser = argparse.ArgumentParser(description="对比两个法律文本文件的差异")
    parser.add_argument("root_path", help="包含法律文本文件的根目录路径")
    parser.add_argument("--threshold", type=float, default=0.35, help="法条匹配的相似度阈值 (默认: 0.35)")
    args = parser.parse_args()
    
    root_pth = args.root_path
    old_file = os.path.join(root_pth, "old_law.txt")
    new_file = os.path.join(root_pth, "new_law.txt") 
    threshold = args.threshold
    
    stats = compare_law_files(old_file, new_file, output_dir="diffRes_"+root_pth, threshold=threshold)
    print(f"对比完成。")
    print(f"旧版法条总数: {stats['old_count']}")
    print(f"新版法条总数: {stats['new_count']}")
    print(f"匹配的法条数: {stats['matched_count']}")
    print(f"删除的法条数: {stats['deleted_count']}")
    print(f"新增的法条数: {stats['added_count']}")

if __name__ == "__main__":
    main()